<?php
/**
 *
 * Digitalus2 CMS
 *
 * @package    	Digitalus\Navigation
 * @copyright  	Copyright (c) 2009,  Digitalus Media USA (http://digitalusmedia.net)
 * @license    	New BSD License, library/Dig/License.txt
 * @version 	2.0
 *
 */
class DigNavigation_Service_Menu {
    const URI_CACHE_KEY = 'digitalus_uris';

    public static function build($parentId = null, $levels = 1, $currentLevel = 1) {
        set_time_limit(0);
        // default to the site root
        if($parentId < 1) {
            $parentId = DigCms_Service_Item::getDefaultItem()->id;
        }
        // fetch the root item
        $parentItem = DigCms_Model_Item::factory($parentId);
        $items = $parentItem->children();
        if($items) {
            $itemsArray = array();
            foreach($items as $item) {
                if($item->isNavigationItem()) {
                    $itemArray = array(
                            'id'    => $item->id,
                            'url'   => self::getUrlForItem($item),
                            'label' => self::getLabel($item),
                            'type'  => $item->namespace
                    );
                    if($levels > $currentLevel) {
                        $childLevel = $currentLevel + 1;
                        $itemArray['children'] = self::build($item->id, $levels, $childLevel);
                    }
                    $itemsArray[] = $itemArray;
                }
            }
            if(count($itemsArray) > 0) {
                return $itemsArray;
            }
        }
    }

    /**
     * builds the url for a given menu item
     *
     * @param int $itemId
     * @return string
     */
    public static function getUrlForItem(DigCms_Model_Item $item) {
        if(DigCms_Service_Item::isDefaultItem($item)) {
            return null;
        }
        $cache = Dig_Service_Core::getInstance()->getCache();
        $cacheKey = 'url_' . $item->id;
        $cachedUrl = $cache->load($cacheKey);
        if($cachedUrl) {
            return $cachedUrl;
        }
        $cacheTags = array('item_' . $item->id);
        
        $links = array();
        $slug = self::getSlug($item);
        if(substr($slug, 0, 1) != '#') {
            $links[] = $slug;
            $appendLink = null;
        } else {
            $appendLink = $slug;
        }
        $parentLinks = array();
        $parents = $item->parents();
        while (count($parents) > 1) {
            $current = array_shift($parents);
            if(DigCms_Service_Item::isDefaultItem($current)) {
                break;
            }
            $cacheTags[] = 'item_' . $current->id;
            $parentLinks[] = self::getSlug($current) . $appendLink;
            $appendLink = null;
        }

        if(count($parentLinks) > 0) {
            $links = array_merge($links, $parentLinks);
        }

        $links = array_reverse($links);
        $uri = strtolower( implode('/', $links) );
        $cache->save($uri, $cacheKey, $cacheTags);

        // save to the uri array
        $uriArray = $cache->load(self::URI_CACHE_KEY);
        if($uriArray) {
            $uriArray = array();
        }
        $uriArray[$item->id] = $uri;
        $cache->save($uriArray, self::URI_CACHE_KEY);
        return $uri;
    }

    public static function getSlug(DigCms_Model_Item $item) {
        if(! empty($item->slug)) {
            $slug = $item->slug;
        } else {
            $slug = strtolower($item->name);
            $slug = str_replace('_', ' ', $slug);
            $slug = str_replace(' ', '-', trim($slug));
        }
        return $slug;
    }

    public static function getLabel(DigCms_Model_Item $item) {
        $defaultLabel = ucwords(str_replace('_', ' ', $item->name));
        return ! empty($item->label) ? $item->label : $defaultLabel;
    }

    public static function mapUrlToItem($url) {
        if(substr($url, 0, 1) == '/') {
            $url = substr($url, 1, strlen($url) - 1);
        }
        // attempt to fetch the item from the uri cache
        $cache = Dig_Service_Core::getInstance()->getCache();
        $uriArray = $cache->load(self::URI_CACHE_KEY);
       // Zend_Debug::dump($uriArray);
        if(is_array($uriArray)) {
            $id = array_search($url, $uriArray);
            if($id > 0) {
                return DigCms_Model_Item::factory($id);
            }
        }
        $cleanUrl = DigNavigation_Service_Url::stripParams($url);
        if(!empty ($cleanUrl)) {
            $urlParts = explode('/', $cleanUrl);
            $parentId = DigCms_Service_Item::getDefaultItem()->id;
            $itemModel = new DigCms_Model_Item();
            foreach ($urlParts as $part) {
                $item = null;
                $select = $itemModel->select();
                $select->where('parent_id = ?', $parentId);
                // first check to see if the node maps to an item label
                $item = $itemModel->findItemByAttributes(array(
                        'slug' => $itemModel->model()->getAdapter()->quoteInto('= ?', $part)
                ));
                if(empty($item)) {
                    $part = strtolower($part);
                    $part = str_replace(' ', '_', $part);
                    $part = str_replace('-', '_', $part);
                    $item = DigCms_Model_Item::getNodeByName($part, $parentId);
                }
                if(!$item) {
                    break;
                }
                $parentId = $item->id;
                //Zend_Debug::dump($item->name, $part);
            }
            if(!$item) {
                // attempt to fetch a legacy URL
                $legacyItem = $itemModel->findItemByAttributes(array(
                    'legacy_url'    => "='{$url}'"
                ));
                // try with a leading slash
                if(!$legacyItem) {
                    $legacyItem = $itemModel->findItemByAttributes(array(
                        'legacy_url'    => "='/{$url}'"
                    ));
                }
                if($legacyItem) {
                    // set 301 redirect header
                    $response = Zend_Controller_Front::getInstance()->getResponse();
                    $response->setRedirect(self::getUrlForItem($legacyItem), 301);
                    $item = $legacyItem;
                }
            }
            return $item;
        } else {
            // this is the index page
            return DigCms_Service_Item::getDefaultItem();
        }
    }



    public static function getUrlList($namespace = null) {
        $list = array();
        $itemModel = new DigCms_Model_Item();
        if($namespace != null) {
            $select = $itemModel->select(false);
            $select->where('namespace = ?', $namespace);
        } else {
            $select = $itemModel->select(false);
        }
        $items = $itemModel->fetchAll($select);
        if($items) {
            foreach ($items as $item) {
                $url = self::getUrlForItem($item);
                $list[$url] = $item->id;
            }

            // now sort the list and flip it so the key is the id
            ksort($list);

            return array_flip($list);
        }
    }

    /**
     * determines if the uri that you pass in is currently selected
     *
     * this matches against the request uri
     *
     * @param string $uri
     * @return boolean
     */
    public static function isSelected($uri) {
        $request = $_SERVER['REQUEST_URI'];

        $requestArray = explode('/', $request);
        if($requestArray[0] == "") {
            array_shift($requestArray);
        }
        $uriArray = explode('/', $uri);

        if(count($uriArray) > 0) {
            $i = 0;
            foreach($uriArray as $part) {
                if(!isset($requestArray[$i]) || $part != $requestArray[$i]) {
                    return false;
                }
                $i++;
            }
            return true;
        }
        return false;
    }

}
?>